<

パフォーマンスプロファイリング

モバイル アプリに関しては、パフォーマンスはユーザー エクスペリエンスにとって非常に重要です。 ユーザーは、アプリがスムーズなスクロールと意味のあるアニメーションを備えていることを期待しています。 「ジャンク」として知られる、途切れやフレームのスキップ。アプリが確実に動作することを確認する方法 さまざまなデバイスでジャンクは発生していませんか?

オプションは 2 つあります。まず、別のデバイスでアプリを手動でテストします。 このアプローチは小規模なアプリでは機能するかもしれませんが、より多くのアプリになると、 アプリのサイズが大きくなると面倒になります。あるいは、統合を実行します 特定のタスクを実行し、パフォーマンスのタイムラインを記録するテスト。 次に、結果を調べて、特定のセクションが アプリを改善する必要があります。

このレシピでは、パフォーマンスを記録するテストの作成方法を学びます。 特定のタスクの実行中にタイムラインを表示し、その概要を保存します。 結果をローカル ファイルに保存します。

このレシピでは次の手順を使用します。

  1. 項目のリストをスクロールするテストを作成します。
  2. アプリのパフォーマンスを記録します。
  3. 結果をディスクに保存します。
  4. テストを実行します。
  5. 結果を確認します。

1. 項目のリストをスクロールするテストを作成します。

このレシピでは、アプリがスクロールするときのパフォーマンスを記録します。 アイテムのリスト。パフォーマンス プロファイリングに焦点を当てるために、このレシピは次のように構築します。 でスクロールウィジェットテストのレシピ。

そのレシピの指示に従ってアプリを作成し、テストを作成します。 すべてが期待どおりに動作することを確認します。

2. アプリのパフォーマンスを記録する

次に、アプリがスクロールするときのパフォーマンスを記録します。 リスト。このタスクを実行するには、traceAction()によって提供されるメソッドIntegrationTestWidgetsFlutterBindingクラス。

このメソッドは、提供された関数を実行し、Timelineアプリのパフォーマンスに関する詳細情報が含まれます。この例 項目のリストをスクロールする機能を提供します。 特定の項目が表示されていることを確認します。機能が完了すると、 のtraceAction()レポートデータを作成しますMapが含まれているTimeline

を指定します。reportKey複数実行する場合traceAction。 デフォルトではすべてTimelinesキーと一緒に保存されますtimeline、 この例では、reportKeyに変更されますscrolling_timeline

await binding.traceAction(
  () async {
    // Scroll until the item to be found appears.
    await tester.scrollUntilVisible(
      itemFinder,
      500.0,
      scrollable: listFinder,
    );
  },
  reportKey: 'scrolling_timeline',
);

3. 結果をディスクに保存します

パフォーマンスのタイムラインを取得したので、それを確認する方法が必要です。 のTimelineオブジェクトはすべてのイベントに関する詳細情報を提供します それは実行されましたが、結果を確認する便利な方法はありません。

したがって、変換すると、TimelineTimelineSummary。 のTimelineSummary2 つのタスクを実行できるため、作業が簡単になります 結果を確認するには:

  1. 含まれるデータを要約した json ドキュメントをディスクに書き込む 以内Timeline。この概要には、 スキップされたフレームの数、最も遅いビルド時間など。
  2. 完了したものを保存するTimelineディスク上の json ファイルとして。 このファイルは Chrome ブラウザで開くことができます。 トレースツールは次の場所にありますchrome://tracing

結果をキャプチャするには、という名前のファイルを作成します。perf_driver.dartの中にtest_driverフォルダーに移動し、次のコードを追加します。

import 'package:flutter_driver/flutter_driver.dart' as driver;
import 'package:integration_test/integration_test_driver.dart';

Future<void> main() {
  return integrationDriver(
    responseDataCallback: (data) async {
      if (data != null) {
        final timeline = driver.Timeline.fromJson(data['scrolling_timeline']);

        // Convert the Timeline into a TimelineSummary that's easier to
        // read and understand.
        final summary = driver.TimelineSummary.summarize(timeline);

        // Then, write the entire timeline to disk in a json format.
        // This file can be opened in the Chrome browser's tracing tools
        // found by navigating to chrome://tracing.
        // Optionally, save the summary to disk by setting includeSummary
        // to true
        await summary.writeTimelineToFile(
          'scrolling_timeline',
          pretty: true,
          includeSummary: true,
        );
      }
    },
  );
}

integrationDriver関数にはresponseDataCallbackカスタマイズできます。 デフォルトでは、結果はintegration_response_data.jsonファイル、 ただし、この例のような概要を生成するようにカスタマイズできます。

4. テストを実行する

パフォーマンスをキャプチャするためにテストを構成した後Timelineそして保存します 結果の概要をディスクに保存するには、次のコマンドを使用してテストを実行します。

flutter drive \
  --driver=test_driver/perf_driver.dart \
  --target=integration_test/scrolling_test.dart \
  --profile

--profileオプションはアプリを「プロファイル モード」用にコンパイルすることを意味します 「デバッグ モード」ではなく、ベンチマーク結果がより近くなるようにします。 エンドユーザーが体験するもの。

5. 結果を確認する

テストが正常に完了すると、buildのルートにあるディレクトリ プロジェクトには 2 つのファイルが含まれています。

  1. scrolling_summary.timeline_summary.json概要が含まれています。開ける テキスト エディタを使用してファイルに含まれる情報を確認します 内部。より高度な設定を使用すると、次の間隔で概要を保存できます。 テストの実行時間を計測し、結果のグラフを作成します。
  2. scrolling_timeline.timeline.json完全なタイムライン データが含まれています。 次の場所にある Chrome ブラウザのトレース ツールを使用してファイルを開きます。chrome://tracing。トレース ツールが提供するのは、 タイムライン データを検査して発見するための便利なインターフェイス パフォーマンスの問題の原因。

まとめの例

{
  "average_frame_build_time_millis": 4.2592592592592595,
  "worst_frame_build_time_millis": 21.0,
  "missed_frame_build_budget_count": 2,
  "average_frame_rasterizer_time_millis": 5.518518518518518,
  "worst_frame_rasterizer_time_millis": 51.0,
  "missed_frame_rasterizer_budget_count": 10,
  "frame_count": 54,
  "frame_build_times": [
    6874,
    5019,
    3638
  ],
  "frame_rasterizer_times": [
    51955,
    8468,
    3129
  ]
}

完全な例

統合テスト/スクロールテスト.dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';

import 'package:scrolling/main.dart';

void main() {
  final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();

  testWidgets('Counter increments smoke test', (tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(MyApp(
      items: List<String>.generate(10000, (i) => 'Item $i'),
    ));

    final listFinder = find.byType(Scrollable);
    final itemFinder = find.byKey(const ValueKey('item_50_text'));

    await binding.traceAction(
      () async {
        // Scroll until the item to be found appears.
        await tester.scrollUntilVisible(
          itemFinder,
          500.0,
          scrollable: listFinder,
        );
      },
      reportKey: 'scrolling_timeline',
    );
  });
}

test_driver/perf_driver.dart

import 'package:flutter_driver/flutter_driver.dart' as driver;
import 'package:integration_test/integration_test_driver.dart';

Future<void> main() {
  return integrationDriver(
    responseDataCallback: (data) async {
      if (data != null) {
        final timeline = driver.Timeline.fromJson(data['scrolling_timeline']);

        // Convert the Timeline into a TimelineSummary that's easier to
        // read and understand.
        final summary = driver.TimelineSummary.summarize(timeline);

        // Then, write the entire timeline to disk in a json format.
        // This file can be opened in the Chrome browser's tracing tools
        // found by navigating to chrome://tracing.
        // Optionally, save the summary to disk by setting includeSummary
        // to true
        await summary.writeTimelineToFile(
          'scrolling_timeline',
          pretty: true,
          includeSummary: true,
        );
      }
    },
  );
}